﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Triples.Model;

namespace Triples {


    public abstract class Controller {
        public event EventHandler GameComplete;
        public event EventHandler GameOver;
        public event EventHandler SetFound;

        protected CardSet SelectedSet;


        public abstract Board GameBoard {
            get;
        }


        public abstract ScoreCard ScoreBoard {
            get;
        }


        internal LocalScoresTable PersonalScores {
            get;
            private set;
        }


        public string Name {
            get { return "Amanda"; }
        }


        protected bool IsGameComplete {
            get;
            set;
        }


        protected Controller() {
            SelectedSet = new CardSet();
            PersonalScores = new LocalScoresTable();
        }


        protected abstract bool ProcessFoundSet (CardSet set);


        protected virtual void ProcessSelectedCard(IPlayableCard card) {
            /* Base implementation does nothing. */
        }

		
		public void SelectCard (IPlayableCard card) {
			card.IsSelected = SelectedSet.Add (card);
            ProcessSelectedCard(card);

			if (SelectedSet.IsSet()) {

                if (ProcessFoundSet(SelectedSet)) {
                    ScoreBoard.ScoreSet();
                    ReportFoundSet();
                    if (IsGameComplete) ReportGameComplete();
                }

                foreach (IPlayableCard c in SelectedSet) if (null != c) c.IsSelected = false;
				SelectedSet = new CardSet ();
                ProcessSelectedCard(null);
			}
		}

		
		public void DeselectCard (IPlayableCard card) {
			SelectedSet.Remove (card);
            ProcessSelectedCard(null);
			card.IsSelected = false;
		}


        protected IPlayableCard GetNextCard(Deck deck) {
            return deck.CanDraw() ? new PlayableCard(deck.Draw()) : null;
        }


        protected void ReportFoundSet() {
            Report(SetFound);
        }


        private void ReportGameComplete () {
            Report(GameComplete);
            EndGame();
        }


        protected void ReportGameOver() {
            Report(GameOver);
            EndGame();
        }


        private void EndGame() {
            PersonalScores.AddScore(Name, ScoreBoard.Score);
        }


        private void Report(EventHandler ev) {
            if (null != ev) ev(this, new EventArgs());
        }
    }
}
